using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Web.SessionState;
using System.Collections;
namespace Ent.Web.Helper
{
    internal enum Source { Template, Custom, None}
    internal struct ControlInfo
    {
        public string ID;
        public string TypeName;
        public Type Type;
        public string EventHandler;
        public Source Source;
        public object[] Params;
    }
    public class DynamicControl
    {
        private HttpSessionState _session;
        private string sessionObject;
        private TemplateControl tControl;
        public DynamicControl(HttpSessionState session, string name)
        {
            _session = session;
            sessionObject = name;
        }
        public TemplateControl Template
        {
            set
            {
                tControl = value;
            }
        }
        public void Reset()
        {
            _session[this.sessionObject] = null;
        }
        // Create control specified by ControlInfo structure
        public Control CreateTemplateControl(string id, string virtualPath)
        {
            return CreateTemplateControl(id, virtualPath, true);
        }
        private Control CreateTemplateControl(string id, string virtualPath, bool doPersist)
        {
            if (doPersist)
            {
                ControlInfo ci = new ControlInfo();
                ci.ID = id;
                ci.TypeName = virtualPath;
                ci.Source = Source.Template;
                PersistControl(ci);
            }
            Control ctl = tControl.LoadControl(virtualPath);
            ctl.ID = id;
            return ctl;
        }
        public Control CreateCustomTemplateControl(string id, Type type, object[] parameters)
        {
            return CreateCustomTemplateControl(id, type, parameters, true);
        }
        private Control CreateCustomTemplateControl(string id, Type type, object[] parameters, bool doPersist)
        {
            if (doPersist)
            {
                ControlInfo ci = new ControlInfo();
                ci.ID = id;
                ci.TypeName = type.FullName;
                ci.Type = type;
                ci.Params = parameters;
                ci.Source = Source.Custom;
                PersistControl(ci);
            }
            Control ctl = tControl.LoadControl(type, parameters);
            ctl.ID = id;
            return ctl;
        }
        public Control CreateControl(string id, string type)
        {
            return CreateControl(id, type, true);
        }
        private Control CreateControl(string id, string type, bool doPersist)
        {
            if (doPersist)
            {
                ControlInfo c = new ControlInfo();
                c.ID = id;
                c.Source = Source.None;
                c.TypeName = type;
                PersistControl(c);
            }
            //Create the control
            Control ctl = null;
            switch (type)
            {
                case "Button":
                    ctl = new Button();
                    break;
                case "TextBox":
                    ctl = new TextBox();
                    break;
                case "CheckBox":
                    ctl = new CheckBox();
                    break;
                case "Label":
                    ctl = new Label();
                    break;
                case "HiddenField":
                    ctl = new HiddenField();
                    break;
                default:
                    return null;
            }
            ctl.ID = id;
            return ctl;
        }
        private bool CheckIfControlExist(ControlInfo ci)
        {
            bool retValue = false;
            ArrayList al = (ArrayList)_session[this.sessionObject];
            if (al != null)
            {
                if (al.Contains(ci))
                    retValue = true;
            }
            return retValue;
        }
        //Checks if Control Exists
        private Control GetControl(ControlInfo ci)
        {
            Control retValue = null;
            ArrayList al = (ArrayList)_session[this.sessionObject];
            if (al != null)
            {
                if (al.Contains(ci))
                    retValue = CreateControl(ci.ID, ci.TypeName, false);
            }
            return retValue;
        }
        private void PersistControl(ControlInfo ci)
        {
            if (!CheckIfControlExist(ci))
            {
                ArrayList al = (ArrayList)_session[this.sessionObject];
                if (al == null)
                {
                    al = new ArrayList();
                }
                al.Add(ci);
                _session[this.sessionObject] = al;
            }
        }
        public void RemoveControl(string controlId)
        {
            ArrayList al = (ArrayList)_session[this.sessionObject];
            for (int i = 0; i < al.Count; i++)
            {
                ControlInfo ci = (ControlInfo)al[i];
                if (ci.ID == controlId)
                {
                    al.Remove(ci);
                    break;
                }
            }
            _session[this.sessionObject] = al;
        }
        public void ClearControl()
        {
            _session[this.sessionObject] = null;
        }
        public Control[] GetPersistedControls()
        {
            ArrayList al = (ArrayList)_session[this.sessionObject];
            Control[] retValue = null;
            if (al != null)
            {
                retValue = new Control[al.Count];
                int cnt = 0;
                foreach (ControlInfo ci in al)
                {
                    if(ci.Source==Source.Custom)
                        retValue.SetValue(CreateCustomTemplateControl(ci.ID, ci.Type, ci.Params, false), cnt++);
                    else if (ci.Source == Source.Template)
                        retValue.SetValue(CreateTemplateControl(ci.ID, ci.TypeName, false), cnt++);
                    else
                        retValue.SetValue(CreateControl(ci.ID, ci.TypeName, false), cnt++);
                }
            }
            return retValue;
        }
    }
}